package vn.pdg.zoombie.ui.zoomimager;


import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;
import android.view.ViewConfiguration;

public class ImageViewTouch extends ImageViewTouchBase {
	
	private final String TAG = "ImageViewTouch";
	
	// min size of image zoom 
	final float					MIN_ZOOM	= 1f;
	// min size of image zoom to fly
	final float					MIN_ZOOM_FLY	= 1.5f;
	
	protected ScaleGestureDetector	mScaleDetector;
	protected GestureDetector			mGestureDetector;
	protected int							mTouchSlop;
	protected float						mCurrentScaleFactor;
	protected float						mScaleFactor;
	protected int							mDoubleTapDirection;
	protected GestureListener			mGestureListener;
	protected ScaleListener				mScaleListener;
	protected Context mContext;
	private boolean isTouch = false;
	private OnZoomListener onZoomListener;
	final private int SWIPE_MIN_DISTANCE = 100;
	final private int SWIPE_MIN_VELOCITY = 100;
	private onDoubleTapListenner mDoubleTapListener;
	private OnSingleTapListenner mSingleTapListenner;
	
	public ImageViewTouch( Context context, AttributeSet attrs )
	{
		super( context, attrs );
		this.mContext=context;
	}
	
	

	public boolean isTouch() {
		return isTouch;
	}


	public void setTouch(boolean isTouch) {
		this.isTouch = isTouch;
	}
	

	public OnZoomListener getOnZoomListener() {
		return onZoomListener;
	}

	public void setOnZoomListener(OnZoomListener onZoomListener) {
		this.onZoomListener = onZoomListener;
	}

	


	public onDoubleTapListenner getonDoubleTapListener() {
		return mDoubleTapListener;
	}



	public void setonDoubleTapListener(onDoubleTapListenner mDoubleTapListener) {
		this.mDoubleTapListener = mDoubleTapListener;
	}



	public OnSingleTapListenner getonSingleTapListenner() {
		return mSingleTapListenner;
	}



	public void setonSingleTapListenner(OnSingleTapListenner mSingleTapListenner) {
		this.mSingleTapListenner = mSingleTapListenner;
	}



	@Override
	protected void init()
	{
		super.init();
		mTouchSlop = ViewConfiguration.getTouchSlop();
		mGestureListener = new GestureListener();
		mScaleListener = new ScaleListener();
		
		mScaleDetector = new ScaleGestureDetector( getContext(), mScaleListener );
		mGestureDetector = new GestureDetector( getContext(), mGestureListener, null, true );
		mCurrentScaleFactor = 1f;
		mDoubleTapDirection = 1;
	}
	
	@Override
	public void setImageRotateBitmapReset( RotateBitmap bitmap, boolean reset )
	{
		super.setImageRotateBitmapReset( bitmap, reset );
		mScaleFactor = getMaxZoom() / 3;
	}
	
	@Override
	public boolean onTouchEvent( MotionEvent event )
	{
		
		
			mScaleDetector.onTouchEvent( event );
			if ( !mScaleDetector.isInProgress() ) mGestureDetector.onTouchEvent( event );
			int action = event.getAction();
			switch ( action & MotionEvent.ACTION_MASK ) {
				case MotionEvent.ACTION_UP:
					if ( getScale() < 1f ) {
						zoomTo( 1f, 50 );
					}
					break;
			}
			
			return true;
			
		
		
	}
	
	
	@Override
	protected void onZoom( float scale )
	{
		super.onZoom( scale );
		if ( !mScaleDetector.isInProgress() ) mCurrentScaleFactor = scale;
	}
	
	protected float onDoubleTapPost( float scale, float maxZoom )
	{
		if ( mDoubleTapDirection == 1 ) {
			if ( ( scale + ( mScaleFactor * 2 ) ) <= maxZoom ) {
				return scale + mScaleFactor;
			} else {
				mDoubleTapDirection = -1;
				return maxZoom;
			}
		} else {
			mDoubleTapDirection = 1;
			return 1f;
		}
	}
	
	class GestureListener extends GestureDetector.SimpleOnGestureListener {
		
		@Override
		public boolean onDoubleTap( MotionEvent e )
		{
			float scale = getScale();
			float targetScale = scale;
			targetScale = onDoubleTapPost( scale, getMaxZoom() );
			targetScale = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
			mCurrentScaleFactor = targetScale;
			zoomTo( targetScale, e.getX(), e.getY(), 200 );
			invalidate();
			
			if(mDoubleTapListener!=null)
				mDoubleTapListener.onDoubleTap(e);
			
			return super.onDoubleTap( e );
		}
		
		
		@Override
		public boolean onScroll( MotionEvent e1, MotionEvent e2, float distanceX, float distanceY )
		{
			if ( e1 == null || e2 == null ) return false;
			if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
			if ( mScaleDetector.isInProgress() ) return false;
			if ( getScale() == 1f ) return false;
			scrollBy( -distanceX, -distanceY );
			invalidate();
			return super.onScroll( e1, e2, distanceX, distanceY );
		}
		
	
		private boolean mOnFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY){
			if ( e1.getPointerCount() > 1 || e2.getPointerCount() > 1 ) return false;
			if ( mScaleDetector.isInProgress() ) return false;
			
			float diffX = e2.getX() - e1.getX();
			float diffY = e2.getY() - e1.getY();
			
			if ( Math.abs( velocityX ) > 800 || Math.abs( velocityY ) > 800 ) {
				scrollBy( diffX / 2, diffY / 2, 300 );
				invalidate();
			}
			
			
			
			final float ev1x = e1.getX();
			final float ev1y = e1.getY();
			final float ev2x = e2.getX();
			final float ev2y = e2.getY();
			final float xdiff = Math.abs(ev1x - ev2x);
			final float ydiff = Math.abs(ev1y - ev2y);
			final float xvelocity = Math.abs(velocityX);
			final float yvelocity = Math.abs(velocityY);
			if(xvelocity > SWIPE_MIN_VELOCITY && xdiff > SWIPE_MIN_DISTANCE)
			{
				Log.i(TAG, "scale "+ mCurrentScaleFactor);
				Log.i(TAG, "Maxscale "+ getMaxZoom());
				Log.i(TAG, "Minscale "+ MIN_ZOOM);
			
			}

				return super.onFling( e1, e2, velocityX, velocityY );
		}
		@Override
		public boolean onFling( MotionEvent e1, MotionEvent e2, float velocityX, float velocityY )
		{
				return mOnFling(e1, e2, velocityX, velocityY);
			
		}
		@Override
		public boolean onSingleTapUp(MotionEvent e) {

			
			if(mSingleTapListenner!=null)
				mSingleTapListenner.onSingleTap(e);

			return false;
		}
	}
	
	
	class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
		
		@SuppressWarnings( "unused" )
		@Override
		public boolean onScale( ScaleGestureDetector detector )
		{
			float span = detector.getCurrentSpan() - detector.getPreviousSpan();
			float targetScale = mCurrentScaleFactor * detector.getScaleFactor();
			if ( true ) {
				targetScale = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
				zoomTo( targetScale, detector.getFocusX(), detector.getFocusY() );
				mCurrentScaleFactor = Math.min( getMaxZoom(), Math.max( targetScale, MIN_ZOOM ) );
				mDoubleTapDirection = 1;
				invalidate();
				return true;
			}
			return false;
		}
	}
	
	


	

	
}
